'''
from my74HC595 import Chip74HC595

# 创建Chip74HC595对象并配置引脚
# oe 接地
# mr 接正极
# DS(23) STCP(21) SHCP(19)
chip = Chip74HC595(23, 21, 19)

chip.on(0) # 亮第一个 Q0
chip.off(0) # 关第一个
#第一个for循环使LED从左到右分别点亮
#而第二个for循环使它从右向左分别点亮.
while True:
    x = 0x01
    for count in range(8):
        chip.shiftOut(1, x)
        x = x<<1;
        time.sleep_ms(300)
    x = 0x01
    for count in range(8):
        chip.shiftOut(0, x)
        x = x<<1
        time.sleep_ms(300)
'''
from machine import Pin

class Chip74HC595(object):
    def __init__(self, ds: int=18, stcp: int=20, shcp: int=21, oe: int=19):
        self._ds = Pin(ds, Pin.OUT, value=0)
        self._shcp = Pin(shcp, Pin.OUT, value=0)
        self._stcp = Pin(stcp, Pin.OUT, value=0)
        self._oe = Pin(oe, Pin.OUT, value=0)
        self._pins = ['0','0','0','0','0','0','0','0']
        self.enable()

    def shiftOut(self,direction,data): 
        self._shcp.on() 
        self._stcp.on()
        if direction: 
            for i in range(8):
                bit = data << i
                bit = bit & 0x80 
                if bit == 0x80:
                    self._ds.on()
                else:
                    self._ds.off()
                self._shift_bit()
            self._send_data()
        if not direction: 
            for i in range(8):
                bit = data >> i
                bit = bit & 0x01
                if bit == 0x01:
                    self._ds.on()
                else:
                    self._ds.off()
                self._shift_bit()
            self._send_data()
    def on(self,index):
        self._pins[index] = '1'
        self.shiftOut(0,int(hex(int(''.join(self._pins),2)),16))
    def off(self,index):
        self._pins[index] = '0'
        self.shiftOut(0,int(hex(int(''.join(self._pins),2)),16))
    def clear(self):
        for i in range(8):
            self._ds.off()
            self._shift_bit()
        self._send_data()
        self.enable()

    def _shift_bit(self):
        self._shcp.off()
        self._shcp.on()

    def _send_data(self):
        self._stcp.off()
        self._stcp.on()
        
    def disable(self):
        self._oe.on()
    
    def enable(self):
        self._oe.off()